package cn.edu.lsu.integratedsurvey.service.impl;

import cn.edu.lsu.integratedsurvey.bean.Student;
import cn.edu.lsu.integratedsurvey.bean.dto.StudentRegisterDto;
import cn.edu.lsu.integratedsurvey.bean.vo.StudentInfoVo;
import cn.edu.lsu.integratedsurvey.exception.SystemException;
import cn.edu.lsu.integratedsurvey.mapper.StudentMapper;
import cn.edu.lsu.integratedsurvey.service.StudentService;
import cn.edu.lsu.integratedsurvey.tool.BCryptUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.apache.logging.log4j.util.Strings;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @author Jasmine-drs
 * @description 针对表【student(学生表)】的数据库操作Service实现
 * @Date 2024-05-01 10:12:36
 */
@Service
public class StudentServiceImpl extends ServiceImpl<StudentMapper, Student> implements StudentService {

	private final StudentMapper studentMapper;
	private final BCryptUtil bCryptUtil;

	public StudentServiceImpl(StudentMapper studentMapper, BCryptUtil bCryptUtil) {
		this.studentMapper = studentMapper;
		this.bCryptUtil = bCryptUtil;
	}

	@Override
	public StudentInfoVo getStudentByStudentNumber(String studentNumber) {
		if (studentNumber.isBlank())
			throw new RuntimeException("学号不能为空");
		studentNumber = studentNumber.trim();
		if (studentNumber.length() != 11)
			throw new RuntimeException("学号长度错误");
		LambdaQueryWrapper<Student> wrapper = new LambdaQueryWrapper<>();
		wrapper.eq(Student::getStudentNumber, studentNumber);
		Student student = studentMapper.selectOne(wrapper);
		if (student == null)
			throw new RuntimeException("该学号不存在，请联系管理员导入学生信息");
		return StudentInfoVo.convertToVO(student);
	}

	@Override
	public List<StudentInfoVo> getStudentByKeyword(String keyword) {
		keyword = keyword.trim();
//		根据学号、姓名搜索学生
		if (keyword.length() == 11) {
			return Collections.singletonList(getStudentByStudentNumber(keyword));
		} else if (keyword.length() <= 20) {
			LambdaQueryWrapper<Student> wrapper = new LambdaQueryWrapper<>();
			wrapper.like(Student::getName, keyword);
			List<Student> student = studentMapper.selectList(wrapper);
			if (student.isEmpty())
				throw new RuntimeException("该学生不存在，请联系管理员导入学生信息");
			return student.stream().map(StudentInfoVo::convertToVO).toList();
		}
		return List.of();
	}

	@Override
	public void register(StudentRegisterDto studentRegisterDto, Integer operatorId) {
		if (studentRegisterDto.isEmpty())
			throw new RuntimeException("部分学生信息为空");
		if (studentMapper.selectOne(new LambdaQueryWrapper<Student>().eq(Student::getStudentNumber, studentRegisterDto.getStudentNumber())) != null)
			throw new RuntimeException("该学生已存在，请勿重复导入");
		Student student = studentRegisterDto.convertToStudent(operatorId);
		studentMapper.insert(student);
	}

	@Transactional(rollbackFor = Exception.class) // 声明使用事务
	@Override
	public void addBatch(List<StudentRegisterDto> studentRegisterDtoList, Integer operatorId) {
		// 先进行批量校验，减少数据库查询次数
		List<String> studentNumbersToCheck = new ArrayList<>();

		for (StudentRegisterDto studentRegisterDto : studentRegisterDtoList) {
			if (studentRegisterDto.isEmpty()) {
				throw new SystemException("部分学生信息为空", 510);
			}
			studentNumbersToCheck.add(studentRegisterDto.getStudentNumber());
		}

		// 执行批量查询
		List<String> existingNumbers = studentMapper.selectStudentNumbersByIds(studentNumbersToCheck);
		List<String> existingStudentNumbers = new ArrayList<>(existingNumbers);
		// 批量处理已存在的学生信息
		if (!existingStudentNumbers.isEmpty()) {
			throw new SystemException("以下学生已存在，请勿重复导入：" + String.join(", ", existingStudentNumbers), 511);
		}

		// 批量转换并插入学生信息
		List<Student> students = new ArrayList<>();
		for (StudentRegisterDto studentRegisterDto : studentRegisterDtoList) {
			Student student = studentRegisterDto.convertToStudent(operatorId);
			students.add(student);
		}
		studentMapper.insertBatch(students);
	}

	@Override
	public Page<StudentInfoVo> searchStudent(String keyword, Integer pageNumber, Integer pageSize) {
		//			构造查询条件
		Page<Student> studentPage = new Page<>(pageNumber, pageSize);
		LambdaQueryWrapper<Student> studentLambdaQueryWrapper = new LambdaQueryWrapper<>();
//		根据学号、姓名、班级，专业搜索学生
		studentLambdaQueryWrapper.like(Student::getStudentNumber, keyword).or()
				.like(Student::getName, keyword).or()
				.like(Student::getGrade, keyword).or()
				.like(Student::getProfession, keyword);
//			获取学生列表
		Page<Student> studentPage1 = studentMapper.selectPage(studentPage, studentLambdaQueryWrapper);
		List<Student> students = studentPage1.getRecords();

//			转化为学生Vo对象
		List<StudentInfoVo> studentInfoVos = students.stream().map(StudentInfoVo::convertToVO).toList();

//			构造VO分页对象，只有Records不一样，其他都一样
		Page<StudentInfoVo> studentInfoVoPage = new Page<>(studentPage1.getCurrent(),
				studentPage1.getSize(),
				studentPage1.getTotal());
		studentInfoVoPage.setRecords(studentInfoVos);
		return studentInfoVoPage;
	}

    @Override
    public String getName(String studentNumber) {
        LambdaQueryWrapper<Student> eq = new LambdaQueryWrapper<Student>()
                .eq(Student::getStudentNumber, studentNumber);
        String name = studentMapper.selectOne(eq).getName();
        if (Strings.isBlank(name))
            throw new RuntimeException("该学生不存在");
        return name;
    }

    @Override
    public void deleteHistory(Integer studentId) {
        studentMapper.deleteHistoryById(studentId);
    }
}




